#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <sys/stat.h>
#include "stdint.h"
#include "ctype.h"

#define MAX_FILES 100
typedef struct {
    char name[256];
} FileInfo;

typedef struct {
    uint32_t size;
    FileInfo FileInfos[MAX_FILES];
} FileInfo_flag_t;

FileInfo_flag_t FileInfo_flag;
FileInfo_flag_t FileInfo_flag2;


// Linux/macOS实现
void traverse_directory(const char *base_path) {
    static uint32_t count = 0;
    DIR *dir = opendir(base_path);
    if (!dir) {
        fprintf(stderr, "无法打开目录: %s\n", base_path);
        return;
    }
    
    struct dirent *entry;
    while ((entry = readdir(dir)) != NULL) {
        // 跳过当前目录(.)和上级目录(..)
        if (strcmp(entry->d_name, ".") == 0 || 
            strcmp(entry->d_name, "..") == 0) {
            continue;
        }
        
        // 构建完整路径
        char full_path[1024];
        snprintf(full_path, sizeof(full_path), "%s/%s", base_path, entry->d_name);
        
        // 检查是否为目录
        struct stat path_stat;
        if (stat(full_path, &path_stat) != 0) continue;
        
        if (S_ISDIR(path_stat.st_mode)) {
            // 递归处理子目录
            traverse_directory(full_path);
        } else {
            // 处理文件
            
            memcpy(FileInfo_flag.FileInfos[count++].name, full_path, strlen(full_path));

            // printf("文件: %s\n", FileInfo_flag.FileInfos[count - 1].name);
        }
    }
    FileInfo_flag.size = count;
    closedir(dir);
}

// BMP文件处理函数
void process_file(const char *oldpath, char *newpath) {
    // 检查是否是BMP文件（不区分大小写）
    const char *ext = strrchr(oldpath, '.');
    if (!ext) return;
    
    // 转换为小写比较
    char ext_lower[6] = {0};
    for (int i = 0; ext[i] && i < sizeof(ext_lower)-1; i++) {
        ext_lower[i] = tolower(ext[i+1]); // 跳过点号
    }
    
    // 判断是否为bmp后缀
    if (strcmp(ext_lower, "bmp") == 0) {
        // 构建新文件名（替换后缀为.bin）
        strcpy(newpath, oldpath);
        char *new_ext = strrchr(newpath, '.');
        
        if (new_ext) {
            strcpy(new_ext + 1, "bin");
        }
    }
}

int main(int argc, char *argv[]) {
    const int bmpHeaderSize = 70;        // 已知文件头大小（示例值）
    if(argc != 2)
    {
        perror("Useage ./a.out dir");
        return -1;
    }

    traverse_directory(argv[1]);

    for(uint32_t i = 0; i < FileInfo_flag.size; i++)
    {
        process_file(FileInfo_flag.FileInfos[i].name, FileInfo_flag2.FileInfos[i].name);

        FILE *img_file = fopen(FileInfo_flag.FileInfos[i].name, "rb");
        if (!img_file) {
            perror("Error opening image file");
            return EXIT_FAILURE;
        }

        // 获取文件大小
        fseek(img_file, 0, SEEK_END);
        long file_size = ftell(img_file);
        rewind(img_file);

        // 检查文件头大小是否有效
        if (bmpHeaderSize >= file_size) {
            fprintf(stderr, "Header size exceeds file size bmpHeaderSize:%d file_size:%ld\n", bmpHeaderSize, file_size);
            fclose(img_file);
            continue;
        }

        // 计算有效数据大小
        long data_size = file_size - bmpHeaderSize;
        
        // 分配缓冲区（跳过文件头）
        unsigned char *buffer = (unsigned char *)malloc(data_size);
        if (!buffer) {
            perror("Memory allocation failed");
            fclose(img_file);
            return EXIT_FAILURE;
        }

        // 跳过文件头，直接读取有效数据
        fseek(img_file, bmpHeaderSize, SEEK_SET);
        size_t bytes_read = fread(buffer, 1, data_size - 2, img_file);
        if (bytes_read != data_size - 2) {
            perror("Error reading image data");
            free(buffer);
            fclose(img_file);
            return EXIT_FAILURE;
        }
        fclose(img_file);

        // 打开BIN文件
        FILE *bin_file = fopen(FileInfo_flag2.FileInfos[i].name, "wb");
        if (!bin_file) {
            perror("Error creating BIN file");
            free(buffer);
            return EXIT_FAILURE;
        }

        // 执行字节交换：每两个相邻字节交换位置
        for (long i = 0; i < data_size - 3; i += 2) {
            unsigned char temp = buffer[i];
            buffer[i] = buffer[i + 1];
            buffer[i + 1] = temp;
        }

        // 写入BIN文件
        size_t bytes_written = fwrite(buffer, 1, data_size - 2, bin_file);
        if (bytes_written != data_size - 2) {
            perror("Error writing to BIN file");
        }

        free(buffer);
        fclose(bin_file);

        printf("Conversion successful!\n");
        printf("Removed %d bytes header\n", bmpHeaderSize);
        printf("Output file: %s (%ld bytes)\n", FileInfo_flag2.FileInfos[i].name, data_size - 2);

    }
    printf("\n目录遍历完成 count:%d\n", FileInfo_flag.size);
    return EXIT_SUCCESS;
}